home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The CICA Windows Explosion!
/
The CICA Windows Explosion! - Disc 2.iso
/
programr
/
wpjv1n4.zip
/
ROD.ZIP
/
ROD.TXT
< prev
next >
Wrap
Text File
|
1993-02-22
|
6KB
|
122 lines
Accessing Global Variables Across DLL
--------------------------------------
In lasts months WPJ I wrote an introductory DLL article. This
month I wish to share with the many readers of the WPJ (at least that's
what Pete and Mike keep telling us) of a way that I discovered by necessity
of handling global variables across DLLs. I describe my approach as a 'kludge'
but, to me it is a fairly good 'kludge'. Like anything done against the norm
there are some risks; like receiving flammable E-mail about going against
Windows standards, and possibilities that Microsoft will change some things
and therefore in later versions my approach will not work. All of these are
possibilities but, I can live with those for now. Why? Because I think that
it is a feasible kludge and what I will show you is nothing that Windows has
not been doing since version 2.0 and it has not changed yet. That is not to
say that they will not change, but that for now it seems safe to say that
they will not.
Here's some background information on why I chose to use the method
I came up with. Windows already supplies ways of handling global variables
across DLLs, for instance, shared memory, passing far pointers and redeclaring
the variables in the DLL. These methods are workable and I strongly suggest
that they be used. Well, here's the background. I was given the task of
converting two DOS applications over to Windows and making them into one
package. My mission was to get it up and running as quickly as possible. The
original DOS application made use of numerous global variables. So, I decided
to do a straight port, and after demoing the port and management making their
decision, I would convert the App over to DLLs. Well, the first two steps
(ported and mgmt. decision) were completed 7 months later. So, now the big
job was to fix up everything over to DLLs. This was no problem except for
the numerous global variables. Hind sight told me I was stupid for not
dealing with them initially. Handling the global variables the way
Microsoft suggests would mean that a great portion of the code would have
to be rewritten, and you know that there just is never any time to do that.
So, I began to think to myself, and I remembered reading about Micheal Geary's
FIXDS. The same logic he applied to not having to call 'MakeProcInstance' also
applied to what I was thinking.
The stack segment (SS) for DLLs is that of the calling application.
And, the calling apps. DS == SS. Therefore, any global variables (CONST and
BSS) defined in the application is shared with the DLL via SS. The only
problem is that you have no clear way of accessing those variables. In
Windows global variables in segments do not change their offsets, only the
segments can be changed due to memory management. Thus, the offset values of
the global variables will always be at the same location inside the
segment. Knowing this, how do we determine those offsets? The answer is the
MAP file that the compiler will supply for you. The MAP file lists all
global symbols defined in the object file(s), sorted by name and a list
sorted by address. With this information in hand we can make a file of all
the global variables used in the program. The global list should use the
same case as the actual definitions. Also, since the MAP file sorts the variables
by name and thats what we are looking for, the matching variable names and
their offsets, our list file should be sorted, this will speed the search.
I wrote a utility program that I call "getoff.exe", that searches the MAP
file and creates an output constants file of the variables, i.e.,
GLOBAL HEADER FILE INPUT FILE FORMAT OUTPUT FILE FORMAT
------------------ ----------------- -------------------
int variableA; variableA #define VARIABLEA 0x0001
int variableB; variableB #define VARIABLEB 0x0002
int variableC; variableC #define VARIABLEC 0x0003
The outputed constant file is to be inlcuded in the DLL modules.
I forgot to mention one thing. The global variables must be declared inside
the DLLs also. The cleanest way would be to include them in a
global header file. Now with the use of some in-line assembly code the global
variables can be accessed and updated inside the DLL.
#include "consts.h"
#include "global.h"
.
.
.
/* this code sets up the variables inside the DLL */
_asm mov ax, ss:[VARIABLEA]
_asm mov [variableA], ax
_asm mov ax, ss:[VARIABLEB]
_asm mov [variableB], ax
_asm mov ax, ss:[VARIABLEC]
_asm mov [variableC], ax
/* now use the variables like normal */
variableC= variableB;
variableB= variableA;
variableA= variableC;
/* when finish reasign the values to the global */
/* variables defined in the application */
_asm mov ax, [variableA]
_asm mov ss:[VARIABLEA], ax
_asm mov ax, [variableB]
_asm mov ss:[VARIABLEB], ax
_asm mov ax, [variableC]
_asm mov ss:[VARIABLEC], ax
This is all it takes to accomplish the task of using global variables
across DLLs. I created for my companies purposes entry/exit routines that
handle the assigning and re-assigning of the variables, only because our
application has over some 75 to 100 global variables.
Included with this document is the "getoff.exe" utility and its
source, and source and executable example of a DLL accessing a global
variable. To run "getoff" type 'getoff <mapfile name> <input file>'.
As I stated this is only a kludge, this method should only be
used if you do not have time to rewrite code and you have too many global
variables. If you have the fortunate pleasure of creating your own application
try to stay away from global variables, and if you must handle them the way
Microsoft suggests.
Rod Haxton can be reached at (703) 883-0226 or (202) 269-3780.